#include "ParamSetDialog.hpp"

#include <qnamespace.h>

#include <QApplication>

ParamSetDialog::ParamSetDialog(QWidget *parent)
    : QDialog(parent),
      frontColor(defaultFrontColor),
      backColor(defaultBackColor),
      pixelSize(defaultPixelSize),
      borderSize(defaultBorderSize),
      eccLevelIndex(defaultEccLevelIndex)
{
    this->setupUI();
}

QColor ParamSetDialog::getFrontColor() const
{
    return this->frontColor;
}

QColor ParamSetDialog::getBackColor() const
{
    return this->backColor;
}

int ParamSetDialog::getPixelSize() const
{
    return this->pixelSize;
}

int ParamSetDialog::getBorderSize() const
{
    return this->borderSize;
}

qrcodegen::QrCode::Ecc ParamSetDialog::getEccLevel() const
{
    return ParamSetDialog::eccLevelPairs
        .at(this->eccLevelIndex)
        .second;
}

void ParamSetDialog::onResetButtonClicked()
{
    // 各项控件覆盖为默认参数
    this->frontColorPicker->setColor(ParamSetDialog::defaultFrontColor);
    this->backColorPicker->setColor(ParamSetDialog::defaultBackColor);
    this->pixelSizeSpinBox->setValue(ParamSetDialog::defaultPixelSize);
    this->borderSizeSpinBox->setValue(ParamSetDialog::defaultBorderSize);
    this->eccLevelComboBox->setCurrentIndex(ParamSetDialog::defaultEccLevelIndex);

    // 成员变量修改为默认参数
    this->frontColor    = ParamSetDialog::defaultFrontColor;
    this->backColor     = ParamSetDialog::defaultBackColor;
    this->pixelSize     = ParamSetDialog::defaultPixelSize;
    this->borderSize    = ParamSetDialog::defaultBorderSize;
    this->eccLevelIndex = ParamSetDialog::defaultEccLevelIndex;
}

void ParamSetDialog::onCancleButtonClicked()
{
    // 如果点击 “取消” ，则不更新参数
    this->frontColorPicker->setColor(this->frontColor);
    this->backColorPicker->setColor(this->backColor);
    this->pixelSizeSpinBox->setValue(this->pixelSize);
    this->borderSizeSpinBox->setValue(this->borderSize);
    this->eccLevelComboBox->setCurrentIndex(this->eccLevelIndex);

    QDialog::reject();
}

void ParamSetDialog::onAppluttonClicked()
{
    // 如果点击 “应用” ，则更新参数，但不关闭窗口
    this->frontColor    = this->frontColorPicker->getColor();
    this->backColor     = this->backColorPicker->getColor();
    this->pixelSize     = this->pixelSizeSpinBox->value();
    this->borderSize    = this->borderSizeSpinBox->value();
    this->eccLevelIndex = this->eccLevelComboBox->currentIndex();

    emit apply();
}

void ParamSetDialog::onOKuttonClicked()
{
    // 如果点击 “确定” ，则关闭窗口，更新参数
    this->frontColor    = this->frontColorPicker->getColor();
    this->backColor     = this->backColorPicker->getColor();
    this->pixelSize     = this->pixelSizeSpinBox->value();
    this->borderSize    = this->borderSizeSpinBox->value();
    this->eccLevelIndex = this->eccLevelComboBox->currentIndex();

    QDialog::accept();
}

void ParamSetDialog::setupUI()
{
    // 设置窗口标题
    this->setWindowTitle("Parameters");

    // 初始化两个颜色选择器
    this->frontColorPicker = new ColorPicker{ParamSetDialog::defaultFrontColor, this};
    this->backColorPicker  = new ColorPicker{ParamSetDialog::defaultBackColor, this};
    this->frontColor       = ParamSetDialog::defaultFrontColor;
    this->backColor        = ParamSetDialog::defaultBackColor;

    // 初始化像素大小输入控件
    this->pixelSizeSpinBox = new QSpinBox{this};
    this->pixelSizeSpinBox->setRange(
        ParamSetDialog::defaultPixelSizeRange.first,
        ParamSetDialog::defaultPixelSizeRange.second);
    this->pixelSizeSpinBox->setValue(ParamSetDialog::defaultPixelSize);

    // 初始化边框大小输入控件
    this->borderSizeSpinBox = new QSpinBox{this};
    this->borderSizeSpinBox->setRange(
        ParamSetDialog::defaultBorderSizeRange.first,
        ParamSetDialog::defaultBorderSizeRange.second);
    this->borderSizeSpinBox->setValue(ParamSetDialog::defaultBorderSize);

    // 初始化纠错级别下拉栏
    this->eccLevelComboBox = new QComboBox{this};
    QStringList eccLevelList;
    for (const auto &eccLevelPair : ParamSetDialog::eccLevelPairs) {
        eccLevelList.append(eccLevelPair.first);
    }
    this->eccLevelComboBox->addItems(eccLevelList);
    this->eccLevelComboBox->setCurrentIndex(ParamSetDialog::defaultEccLevelIndex);

    // 初始化重置、取消、应用、确定四个按钮
    auto resetButtonIcon  = QApplication::style()->standardIcon(QStyle::SP_DialogResetButton);
    auto cancelButtonIcon = QApplication::style()->standardIcon(QStyle::SP_DialogCancelButton);
    auto applyButtonIcon  = QApplication::style()->standardIcon(QStyle::SP_DialogApplyButton);
    auto okButtonIcon     = QApplication::style()->standardIcon(QStyle::SP_DialogOkButton);
    this->resetButton     = new QPushButton(resetButtonIcon, "Reset");
    this->cancelButton    = new QPushButton(cancelButtonIcon, "Cancel");
    this->applyButton     = new QPushButton(applyButtonIcon, "Apply");
    this->okButton        = new QPushButton(okButtonIcon, "OK");

    // 连接四个按钮的信号槽
    connect(this->resetButton,
            &QPushButton::clicked,
            this,
            &ParamSetDialog::onResetButtonClicked);
    connect(this->cancelButton,
            &QPushButton::clicked,
            this,
            &ParamSetDialog::onCancleButtonClicked);
    connect(this->applyButton,
            &QPushButton::clicked,
            this,
            &ParamSetDialog::onAppluttonClicked);
    connect(this->okButton,
            &QPushButton::clicked,
            this,
            &ParamSetDialog::onOKuttonClicked);

    auto paramSetWidget       = new QWidget{this};
    auto paramSetWidgetLayout = new QGridLayout{paramSetWidget};
    paramSetWidgetLayout->addWidget(new QLabel("Front Color"), 0, 0);
    paramSetWidgetLayout->addWidget(this->frontColorPicker, 0, 1);
    paramSetWidgetLayout->addWidget(new QLabel("Back Color"), 0, 2);
    paramSetWidgetLayout->addWidget(this->backColorPicker, 0, 3);
    paramSetWidgetLayout->addWidget(new QLabel("Pixel Size"), 1, 0);
    paramSetWidgetLayout->addWidget(this->pixelSizeSpinBox, 1, 1);
    paramSetWidgetLayout->addWidget(new QLabel("Border Size"), 1, 2);
    paramSetWidgetLayout->addWidget(this->borderSizeSpinBox, 1, 3);
    paramSetWidgetLayout->addWidget(new QLabel("ECC Level"), 2, 0);
    paramSetWidgetLayout->addWidget(this->eccLevelComboBox, 2, 1);

    auto buttonWidget       = new QWidget{this};
    auto buttonWidgetLayout = new QHBoxLayout{buttonWidget};
    buttonWidgetLayout->addWidget(this->resetButton);
    buttonWidgetLayout->addWidget(this->cancelButton);
    buttonWidgetLayout->addWidget(this->applyButton);
    buttonWidgetLayout->addWidget(this->okButton);
    buttonWidgetLayout->setAlignment(Qt::AlignCenter);

    auto mainLayout = new QVBoxLayout{this};
    mainLayout->addWidget(paramSetWidget);
    mainLayout->addWidget(buttonWidget);
    mainLayout->setAlignment(Qt::AlignTop);
}
